/**
 * FileResourceHyperlinkDetector.java
 * created by wesley at 2008-6-7
 */
package net.sf.filelink.hyperlink;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import net.sf.filelink.utl.QueryUtils;
import net.sf.filelink.utl.XmlEditorUtils;

import org.eclipse.core.resources.IFile;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.w3c.dom.Node;

/**
 * FileResourceHyperlinkDetector
 * 
 * @author wesley
 */
public class FileResourceHyperlinkDetector extends AbstractHyperlinkDetector {

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(
	 * org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion,
	 * boolean)
	 */
	public IHyperlink[] detectHyperlinks(ITextViewer textViewer,
			IRegion region, boolean canShowMultipleHyperlinks) {

		int offset = region.getOffset();

		Node node = XmlEditorUtils.getNodeByOffset(textViewer.getDocument(),
				offset);

		if (node != null
				&& (node.getNodeType() == Node.TEXT_NODE || node.getNodeType() == Node.ATTRIBUTE_NODE)) {

			String nodeInfo = node.getNodeValue();
			if (nodeInfo != null) {
				nodeInfo = nodeInfo.trim();
			}

			IRegion nodeRegion = region;
			try {
				IRegion lineRegion = textViewer.getDocument()
						.getLineInformationOfOffset(offset);
				String lineText = textViewer.getDocument().get(
						lineRegion.getOffset(), lineRegion.getLength());
				int start = lineRegion.getOffset() + lineText.indexOf(nodeInfo);
				nodeRegion = new Region(start, nodeInfo.length());

			} catch (BadLocationException e) {
				e.printStackTrace();
			}

			return findHyperlinks(nodeRegion, nodeInfo);

		} else {
			return null;
		}
	}

	private IHyperlink[] findHyperlinks(IRegion nodeRegion, String nodeInfo) {

		Set<IHyperlink> hyperLinks = new LinkedHashSet<IHyperlink>();

		// search file by path
		String filePath = QueryUtils.toFilePath(nodeInfo);
		List<IFile> fileList = QueryUtils.findFileResources(filePath,
				QueryUtils.getSearchFolders());
		for (IFile file : fileList) {
			IHyperlink hyperlink = new FileResourceHyperlink(nodeRegion,
					nodeInfo, file);
			hyperLinks.add(hyperlink);
		}

		// search file by name
		String fileName = QueryUtils.toFileName(nodeInfo);
		if (!fileName.equals(filePath)) {
			fileList = QueryUtils.findFileResources(fileName, QueryUtils
					.getSearchFolders());
			for (IFile file : fileList) {
				IHyperlink hyperlink = new FileResourceHyperlink(nodeRegion,
						nodeInfo, file);
				hyperLinks.add(hyperlink);
			}
		}
		if (hyperLinks.isEmpty()) {
			// add "file not found" information

			IHyperlink hyperlink = new FileResourceHyperlink(nodeRegion,
					nodeInfo, null);
			hyperLinks.add(hyperlink);
		}

		return hyperLinks.toArray(new IHyperlink[0]);
	}
}
